package com.haixiaoke.saas.house.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.haixiaoke.saas.cleaner.domain.Cleaner;
import com.haixiaoke.saas.cleaner.domain.InspectionProcessRecord;
import com.haixiaoke.saas.cleaner.domain.InspectionProcessRecordTree;
import com.haixiaoke.saas.cleaner.domain.SweepProcessRecord;
import com.haixiaoke.saas.cleaner.service.ICleanerService;
import com.haixiaoke.saas.cleaner.service.IInspectionProcessRecordService;
import com.haixiaoke.saas.cleaner.service.ISweepProcessRecordService;
import com.haixiaoke.saas.common.config.sms.SmsConfig;
import com.haixiaoke.saas.common.constant.HouseConstants;
import com.haixiaoke.saas.common.constant.TenantConstants;
import com.haixiaoke.saas.common.core.domain.AjaxResult;
import com.haixiaoke.saas.common.enums.CleanerEnum;
import com.haixiaoke.saas.common.enums.HouseInspectionEnum;
import com.haixiaoke.saas.common.enums.HouseSweepEnum;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.tenant.TenantContext;
import com.haixiaoke.saas.common.utils.DateUtils;
import com.haixiaoke.saas.common.utils.sms.SmsUtils;
import com.haixiaoke.saas.department.domain.Tenant;
import com.haixiaoke.saas.department.service.ITenantService;
import com.haixiaoke.saas.house.domain.*;
import com.haixiaoke.saas.house.mapper.HouseInspectionMapper;
import com.haixiaoke.saas.house.service.*;
import com.haixiaoke.saas.order.domain.Order;
import com.haixiaoke.saas.order.service.IOrderService;
import com.haixiaoke.saas.user.domain.BizUserBusiness;
import com.haixiaoke.saas.user.service.IBizUserBusinessService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 验房记录Service业务层处理
 *
 * @author xiaolong
 * @date 2024-05-08
 */
@Service
public class HouseInspectionServiceImpl implements IHouseInspectionService {
    @Autowired
    private HouseInspectionMapper houseInspectionMapper;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IHouseService houseService;
    @Autowired
    private ICleanerService cleanerService;
    @Autowired
    private IBizUserBusinessService bizUserBusinessService;
    @Autowired
    private SmsUtils smsUtils;
    @Autowired
    private SmsConfig smsConfig;
    @Autowired
    private ICleaningProcessService cleaningProcessService;
    @Autowired
    private IInspectionProcessRecordService iInspectionProcessRecordService;
    @Autowired
    private IInspectionProcessRecordService inspectionProcessRecordService;
    @Autowired
    private ITenantService departmentService;
    @Autowired
    private IHouseSweepService houseSweepService;
    @Autowired
    private ISweepProcessRecordService sweepProcessRecordService;
    @Autowired
    private IHousePictureService housePictureService;

    /**
     * 查询验房记录
     *
     * @param houseInspectionId 验房记录主键
     * @return 验房记录
     */
    @Override
    public HouseInspection selectHouseInspectionByHouseInspectionId(String houseInspectionId) {
        HouseInspection houseInspection = houseInspectionMapper.selectHouseInspectionByHouseInspectionId(houseInspectionId);
        if (ObjectUtil.isEmpty(houseInspection)) {
            throw new ServiceException("数据已被删除，请刷新后再试");
        }
        InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
        inspectionProcessRecord.setHouseInspectionId(houseInspectionId);
        inspectionProcessRecord.setTenantId(TenantContext.getTenantId());
        List<InspectionProcessRecordTree> list = iInspectionProcessRecordService.selectInspectionProcessRecordTree(inspectionProcessRecord);
        houseInspection.setInspectionProcessRecordTreeList(list);
        return houseInspection;
    }

    /**
     * 查询验房记录列表
     *
     * @param houseInspection 验房记录
     * @return 验房记录
     */
    @Override
    public List<HouseInspection> selectHouseInspectionList(HouseInspection houseInspection) {
        return houseInspectionMapper.selectHouseInspectionList(houseInspection);
    }

    /**
     * 新增验房记录
     *
     * @param houseInspection 验房记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertHouseInspection(HouseInspection houseInspection) {
        if (houseInspection.getScheduledTime() == null || houseInspection.getScheduledTime().equals("")) {
            throw new ServiceException("请选择预计开始时间");
        }
        Order order = orderService.selectOrderById(houseInspection.getOrderId());
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        House house = houseService.selectHouseById(order.getHouseId());
        if (house == null) {
            throw new ServiceException("房源不存在");
        }
        Tenant tenant = departmentService.selectDepByDepId(TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(tenant)) {
            throw new ServiceException("租户不存在");
        }

        CleaningProcess cleaningProcess = new CleaningProcess();
        cleaningProcess.setTenantId(TenantContext.getTenantId());
        cleaningProcess.setHouseId(house.getHouseId());
        List<CleaningProcess> cleaningProcessList = cleaningProcessService.selectCleaningProcessList(cleaningProcess);
        if (CollectionUtil.isEmpty(cleaningProcessList)) {
            throw new ServiceException("房间未设置保洁流程");
        }


        // 自动派单
        if (TenantConstants.ORDER_ALLOCATION_STATE_YES.equals(tenant.getOrderAllocationState())) {
            Cleaner cleaner = new Cleaner();
            cleaner.setTenantId(TenantContext.getTenantId());
            cleaner.setCleanerType(CleanerEnum.CLEANER_TYPE_INSPECTION.getValue());
            List<Cleaner> cleanerList = cleanerService.selectCleanerList(cleaner);
            if (CollectionUtil.isEmpty(cleanerList)) {
                return insertHouseInspection(houseInspection, order, house, cleaningProcessList);
            }
            List<Cleaner> newCleanerList = new ArrayList<>();
            for (Cleaner cleaner1 : cleanerList) {
                if (cleaner1.getCleanerScope().equals(CleanerEnum.CLEANER_SCOPE_ALL.getValue())) {
                    newCleanerList.add(cleaner1);
                } else {
                    if (cleaner1.getEstateIds().contains(house.getEstateId())) {
                        newCleanerList.add(cleaner1);
                    }
                }
            }
            if (CollectionUtil.isEmpty(newCleanerList)) {
                return insertHouseInspection(houseInspection, order, house, cleaningProcessList);
            }
            List<Long> cleanerIds = newCleanerList.stream().map(Cleaner::getCleanerId).collect(Collectors.toList());
            Long[] cleanerIdsArray = cleanerIds.toArray(new Long[cleanerIds.size()]);
            cleaner.setCleanerIds(cleanerIdsArray);
            cleaner.setCreateTime(new Date());


            List<Cleaner> cleaners = cleanerService.selectCleanerByCleanerList(cleaner);
            List<Long> clenanerIdList = cleaners.stream().map(Cleaner::getCleanerId).collect(Collectors.toList());
            if (clenanerIdList.size() == 0) {
                Random random = new Random();
                int nexted = random.nextInt(newCleanerList.size());
                Long cleanerId = cleanerIds.get(nexted);
                houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_EXCHANGE.getValue());
                return sendInspection(houseInspection, order, house, cleaningProcessList, cleanerId);

            } else {
                if (cleanerIds.size() > clenanerIdList.size()) {
                    cleanerIds.removeAll(clenanerIdList);
                    Random random = new Random();
                    int nexted = random.nextInt(cleanerIds.size());
                    Long cleanerId = cleanerIds.get(nexted);
                    houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_EXCHANGE.getValue());
                    return sendInspection(houseInspection, order, house, cleaningProcessList, cleanerId);
                } else {
                    Random random = new Random();
                    int nexted = random.nextInt(cleanerIds.size());
                    Long cleanerId = cleanerIds.get(nexted);
                    houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_EXCHANGE.getValue());
                    return sendInspection(houseInspection, order, house, cleaningProcessList, cleanerId);
                }

            }
        }

        return insertHouseInspection(houseInspection, order, house, cleaningProcessList);
    }

    private int insertHouseInspection(HouseInspection houseInspection, Order order, House house, List<CleaningProcess> cleaningProcessList) {
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_NO.getValue());
        houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_EXCHANGE.getValue());
        houseInspection.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        houseInspection.setOrderId(order.getOrderId());
        houseInspection.setHouseId(house.getHouseId());
        String houseInspectionId = "I" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseInspection.setHouseInspectionId(houseInspectionId);
        houseInspection.setCreateTime(DateUtils.getNowDate());
        houseInspectionMapper.insertHouseInspection(houseInspection);

        List<InspectionProcessRecord> inspectionProcessRecordList = new ArrayList<>();
        for (CleaningProcess process : cleaningProcessList) {
            InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
            inspectionProcessRecord.setHouseInspectionId(houseInspection.getHouseInspectionId());
            inspectionProcessRecord.setTenantId(houseInspection.getTenantId());
            inspectionProcessRecord.setCleaningProcessId(process.getId());
            inspectionProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
            inspectionProcessRecord.setParentId(process.getParentId());
            inspectionProcessRecord.setSort(process.getSort());
            inspectionProcessRecord.setCreateTime(new Date());
            inspectionProcessRecordList.add(inspectionProcessRecord);
        }

        iInspectionProcessRecordService.insertInspectionProcessRecordList(inspectionProcessRecordList);
        return 1;
    }

    /**
     * 指定验房人员
     *
     * @param houseInspection 验房记录
     * @return 结果
     */
    @Override
    public int updateHouseInspection(HouseInspection houseInspection) {
        HouseInspection byHouseInspectionId = houseInspectionMapper.selectHouseInspectionByHouseInspectionId(houseInspection.getHouseInspectionId());
        if (!TenantContext.getTenantId().equals(byHouseInspectionId.getTenantId())) {
            return 0;
        }
        if (!byHouseInspectionId.getInspectionState().equals(HouseInspectionEnum.INSPECTION_STATE_NO.getValue())) {
            throw new ServiceException("数据状态异常，请刷新后再试");
        }
        if (houseInspection.getCleanerId() == null || houseInspection.getCleanerId().equals("")) {
            throw new ServiceException("请选择验房员");
        }
        Cleaner cleaner = cleanerService.selectCleanerByCleanerId(houseInspection.getCleanerId());
        if (ObjectUtil.isEmpty(cleaner)) {
            throw new ServiceException("验房员不存在");
        }
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_YES.getValue());
        houseInspection.setHomeInspectorName(cleaner.getCleanerName());
        houseInspection.setUpdateTime(DateUtils.getNowDate());
        houseInspection.setCleanerUserId(cleaner.getCleanerUserId());
        houseInspection.setVersion(byHouseInspectionId.getVersion());
        int i = houseInspectionMapper.updateHouseInspection(houseInspection);
        if (i == 0) {
            return 0;
        }


        // 短信通知
        BizUserBusiness userBusiness = bizUserBusinessService.selectBizUserBusinessByUserId(cleaner.getCleanerUserId(), TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(userBusiness)) {
            throw new ServiceException("企业用户不存在");
        }
        Boolean smsWithData = smsUtils.sendTemplateSmsWithData(userBusiness.getPhonenumber(), smsConfig.getInspectionTemplateCode(), new String[]{DateUtil.formatDateTime(byHouseInspectionId.getScheduledTime()), byHouseInspectionId.getFullAddress()});
        if (smsWithData) {
            return 1;
        }
        return 0;
    }

    /**
     * 批量删除验房记录
     *
     * @param houseInspectionIds 需要删除的验房记录主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteHouseInspectionByHouseInspectionIds(String[] houseInspectionIds) {
        HouseInspection houseInspection = new HouseInspection();
        houseInspection.setTenantId(TenantContext.getTenantId());
        houseInspection.setHouseInspectionIds(houseInspectionIds);
        List<HouseInspection> houseInspectionList = houseInspectionMapper.selectHouseInspectionByHouseInspectionIds(houseInspection);
        if (houseInspectionList.size() < houseInspectionIds.length) {
            return 0;
        }
        houseInspectionMapper.updateHouseInspectionByHouseInspectionIds(houseInspection);
        InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
        inspectionProcessRecord.setTenantId(TenantContext.getTenantId());
        inspectionProcessRecord.setHouseInspectionIds(houseInspectionIds);
        inspectionProcessRecordService.updateInspectionProcessRecordByHouseInspectionIds(inspectionProcessRecord);
        return 1;
    }

    /**
     * 删除验房记录信息
     *
     * @param houseInspectionId 验房记录主键
     * @return 结果
     */
    @Override
    public int deleteHouseInspectionByHouseInspectionId(String houseInspectionId) {
        return houseInspectionMapper.deleteHouseInspectionByHouseInspectionId(houseInspectionId);
    }


    /**
     * 更换验房人员
     */
    @Override
    public int changeHouseInspection(HouseInspection houseInspection) {
        HouseInspection byHouseInspectionId = houseInspectionMapper.selectHouseInspectionByHouseInspectionId(houseInspection.getHouseInspectionId());
        if (!TenantContext.getTenantId().equals(byHouseInspectionId.getTenantId())) {
            return 0;
        }
        String homeInspectorName = byHouseInspectionId.getHomeInspectorName();
        if (!byHouseInspectionId.getInspectionState().equals(HouseInspectionEnum.INSPECTION_STATE_YES.getValue())) {
            throw new ServiceException("数据状态异常，请刷新后再试");
        }
        if (houseInspection.getCleanerId() == null || houseInspection.getCleanerId().equals("")) {
            throw new ServiceException("请选择验房员");
        }
        Cleaner cleaner = cleanerService.selectCleanerByCleanerId(byHouseInspectionId.getCleanerId());
        if (ObjectUtil.isEmpty(cleaner)) {
            throw new ServiceException("验房员不存在");
        }
        Cleaner newCleaner = cleanerService.selectCleanerByCleanerId(houseInspection.getCleanerId());
        if (ObjectUtil.isEmpty(newCleaner)) {
            throw new ServiceException("验房员不存在");
        }
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_YES.getValue());
        houseInspection.setHomeInspectorName(newCleaner.getCleanerName());
        houseInspection.setUpdateTime(DateUtils.getNowDate());
        houseInspection.setCleanerUserId(newCleaner.getCleanerUserId());
        houseInspection.setVersion(byHouseInspectionId.getVersion());
        int i = houseInspectionMapper.updateHouseInspection(houseInspection);
        if (i == 0) {
            return 0;
        }

        // 短信通知
        BizUserBusiness userBusiness = bizUserBusinessService.selectBizUserBusinessByUserId(cleaner.getCleanerUserId(), TenantContext.getTenantId());
        BizUserBusiness newUserBusiness = bizUserBusinessService.selectBizUserBusinessByUserId(newCleaner.getCleanerUserId(), TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(userBusiness) || ObjectUtil.isEmpty(newUserBusiness)) {
            throw new ServiceException("企业用户不存在");
        }
        Boolean smsWithData = smsUtils.sendTemplateSmsWithData(userBusiness.getPhonenumber(), smsConfig.getExchangeInspectionTemplateCode(), new String[]{homeInspectorName, DateUtil.formatDateTime(byHouseInspectionId.getScheduledTime()), byHouseInspectionId.getFullAddress()});
        Boolean smsData = smsUtils.sendTemplateSmsWithData(newUserBusiness.getPhonenumber(), smsConfig.getInspectionTemplateCode(), new String[]{DateUtil.formatDateTime(byHouseInspectionId.getScheduledTime()), byHouseInspectionId.getFullAddress()});
        if (smsWithData && smsData) {
            return 1;
        }
        return 0;
    }

    @Override
    @Transactional
    public int routineInspection(HouseInspection houseInspection) {
        if (houseInspection.getScheduledTime() == null || houseInspection.getScheduledTime().equals("")) {
            throw new ServiceException("请选择预计开始时间");
        }
        if (StrUtil.isEmpty(houseInspection.getHouseId())) {
            throw new ServiceException("请选择房间");
        }
        House house = houseService.selectHouseById(houseInspection.getHouseId());
        if (house == null) {
            throw new ServiceException("房源不存在");
        }

        Tenant tenant = departmentService.selectDepByDepId(TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(tenant)) {
            throw new ServiceException("租户不存在");
        }

        CleaningProcess cleaningProcess = new CleaningProcess();
        cleaningProcess.setTenantId(TenantContext.getTenantId());
        cleaningProcess.setHouseId(house.getHouseId());
        List<CleaningProcess> cleaningProcessList = cleaningProcessService.selectCleaningProcessList(cleaningProcess);
        if (CollectionUtil.isEmpty(cleaningProcessList)) {
            throw new ServiceException("房间未设置保洁流程");
        }


        // 自动派单
        if (TenantConstants.ORDER_ALLOCATION_STATE_YES.equals(tenant.getOrderAllocationState())) {
            Cleaner cleaner = new Cleaner();
            cleaner.setTenantId(TenantContext.getTenantId());
            cleaner.setCleanerType(CleanerEnum.CLEANER_TYPE_INSPECTION.getValue());
            List<Cleaner> cleanerList = cleanerService.selectCleanerList(cleaner);
            if (CollectionUtil.isEmpty(cleanerList)) {
                return addHouseInspection(houseInspection, house, cleaningProcessList);
            }
            List<Cleaner> newCleanerList = new ArrayList<>();
            for (Cleaner cleaner1 : cleanerList) {
                if (cleaner1.getCleanerScope().equals(CleanerEnum.CLEANER_SCOPE_ALL.getValue())) {
                    newCleanerList.add(cleaner1);
                } else {
                    if (cleaner1.getEstateIds().contains(house.getEstateId())) {
                        newCleanerList.add(cleaner1);
                    }
                }
            }
            if (CollectionUtil.isEmpty(newCleanerList)) {
                return addHouseInspection(houseInspection, house, cleaningProcessList);
            }
            List<Long> cleanerIds = newCleanerList.stream().map(Cleaner::getCleanerId).collect(Collectors.toList());
            Long[] cleanerIdsArray = cleanerIds.toArray(new Long[cleanerIds.size()]);
            cleaner.setCleanerIds(cleanerIdsArray);
            cleaner.setCreateTime(new Date());


            List<Cleaner> cleaners = cleanerService.selectCleanerByCleanerList(cleaner);
            List<Long> clenanerIdList = cleaners.stream().map(Cleaner::getCleanerId).collect(Collectors.toList());
            if (clenanerIdList.size() == 0) {
                Random random = new Random();
                int nexted = random.nextInt(newCleanerList.size());
                Long cleanerId = cleanerIds.get(nexted);
                houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_ORDINARILY.getValue());
                return sendInspection(houseInspection, null, house, cleaningProcessList, cleanerId);

            } else {
                if (cleanerIds.size() > clenanerIdList.size()) {
                    cleanerIds.removeAll(clenanerIdList);
                    Random random = new Random();
                    int nexted = random.nextInt(cleanerIds.size());
                    Long cleanerId = cleanerIds.get(nexted);
                    houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_ORDINARILY.getValue());
                    return sendInspection(houseInspection, null, house, cleaningProcessList, cleanerId);
                } else {
                    Random random = new Random();
                    int nexted = random.nextInt(cleanerIds.size());
                    Long cleanerId = cleanerIds.get(nexted);
                    houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_ORDINARILY.getValue());
                    return sendInspection(houseInspection, null, house, cleaningProcessList, cleanerId);
                }

            }
        }

        return addHouseInspection(houseInspection, house, cleaningProcessList);
    }

    private int addHouseInspection(HouseInspection houseInspection, House house, List<CleaningProcess> cleaningProcessList) {
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_NO.getValue());
        houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_ORDINARILY.getValue());
        houseInspection.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        houseInspection.setHouseId(house.getHouseId());
        String houseInspectionId = "I" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseInspection.setHouseInspectionId(houseInspectionId);
        houseInspection.setCreateTime(DateUtils.getNowDate());
        houseInspectionMapper.insertHouseInspection(houseInspection);

        List<InspectionProcessRecord> inspectionProcessRecordList = new ArrayList<>();
        for (CleaningProcess process : cleaningProcessList) {
            InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
            inspectionProcessRecord.setHouseInspectionId(houseInspection.getHouseInspectionId());
            inspectionProcessRecord.setTenantId(houseInspection.getTenantId());
            inspectionProcessRecord.setCleaningProcessId(process.getId());
            inspectionProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
            inspectionProcessRecord.setParentId(process.getParentId());
            inspectionProcessRecord.setSort(process.getSort());
            inspectionProcessRecord.setCreateTime(new Date());
            inspectionProcessRecordList.add(inspectionProcessRecord);
        }

        iInspectionProcessRecordService.insertInspectionProcessRecordList(inspectionProcessRecordList);
        return 1;
    }


    /**
     * 新增同一人验房打扫
     */
    @Override
    @Transactional
    public AjaxResult insertSweepAndInspection(HouseInspection houseInspection) {
        if (houseInspection.getScheduledTime() == null || houseInspection.getScheduledTime().equals("")) {
            throw new ServiceException("请选择预计开始时间");
        }
        Order order = orderService.selectOrderById(houseInspection.getOrderId());
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        House house = houseService.selectHouseById(order.getHouseId());
        if (house == null) {
            throw new ServiceException("房源不存在");
        }
        Tenant tenant = departmentService.selectDepByDepId(TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(tenant)) {
            throw new ServiceException("租户不存在");
        }
        CleaningProcess cleaningProcess = new CleaningProcess();
        cleaningProcess.setTenantId(TenantContext.getTenantId());
        cleaningProcess.setHouseId(house.getHouseId());
        List<CleaningProcess> cleaningProcessList = cleaningProcessService.selectCleaningProcessList(cleaningProcess);
        if (CollectionUtil.isEmpty(cleaningProcessList)) {
            throw new ServiceException("房间未设置保洁流程");
        }

        if (!TenantConstants.ORDER_ALLOCATION_STATE_YES.equals(tenant.getOrderAllocationState())) {
            // addSweepAndInspection(houseInspection, order, house, cleaningProcessList);
            return AjaxResult.error("此功能需开启自动派单");
        }
        Cleaner cleaner = new Cleaner();
        cleaner.setTenantId(TenantContext.getTenantId());
        cleaner.setCleanerType(CleanerEnum.CLEANER_TYPE_ALL.getValue());
        List<Cleaner> cleanerList = cleanerService.selectCleanerList(cleaner);
        if (CollectionUtil.isEmpty(cleanerList)) {
            // addSweepAndInspection(houseInspection, order, house, cleaningProcessList);
            return AjaxResult.error("小区无对应职责人员");
        }
        List<Cleaner> newCleanerList = new ArrayList<>();
        for (Cleaner cleaner1 : cleanerList) {
            if (cleaner1.getCleanerScope().equals(CleanerEnum.CLEANER_SCOPE_ALL.getValue())) {
                newCleanerList.add(cleaner1);
            } else {
                if (cleaner1.getEstateIds().contains(house.getEstateId())) {
                    newCleanerList.add(cleaner1);
                }
            }
        }
        if (CollectionUtil.isEmpty(newCleanerList)) {
            return AjaxResult.error("小区无对应职责人员");
        }
        List<Long> cleanerIds = newCleanerList.stream().map(Cleaner::getCleanerId).collect(Collectors.toList());
        Long[] cleanerIdsArray = cleanerIds.toArray(new Long[cleanerIds.size()]);
        cleaner.setCleanerIds(cleanerIdsArray);
        cleaner.setCreateTime(new Date());


        List<Cleaner> cleaners = cleanerService.selectCleanerByCleanerList(cleaner);
        List<Long> clenanerIdList = cleaners.stream().map(Cleaner::getCleanerId).collect(Collectors.toList());
        if (clenanerIdList.size() == 0) {
            Random random = new Random();
            int nexted = random.nextInt(newCleanerList.size());
            Long cleanerId = cleanerIds.get(nexted);
            return sweepAndInspection(houseInspection, order, house, cleaningProcessList, cleanerId);

        } else {
            if (cleanerIds.size() > clenanerIdList.size()) {
                cleanerIds.removeAll(clenanerIdList);
                Random random = new Random();
                int nexted = random.nextInt(cleanerIds.size());
                Long cleanerId = cleanerIds.get(nexted);
                return sweepAndInspection(houseInspection, order, house, cleaningProcessList, cleanerId);
            } else {
                Random random = new Random();
                int nexted = random.nextInt(cleanerIds.size());
                Long cleanerId = cleanerIds.get(nexted);
                return sweepAndInspection(houseInspection, order, house, cleaningProcessList, cleanerId);
            }

        }

    }

    private void addSweepAndInspection(HouseInspection houseInspection, Order order, House house, List<CleaningProcess> cleaningProcessList) {
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_NO.getValue());
        houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_EXCHANGE.getValue());
        houseInspection.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        houseInspection.setOrderId(order.getOrderId());
        houseInspection.setHouseId(house.getHouseId());
        String houseInspectionId = "I" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseInspection.setHouseInspectionId(houseInspectionId);
        houseInspection.setCreateTime(DateUtils.getNowDate());
        houseInspectionMapper.insertHouseInspection(houseInspection);

        HouseSweep houseSweep = new HouseSweep();
        houseSweep.setOperatorId(houseInspection.getOperatorId());
        houseSweep.setTenantId(houseInspection.getTenantId());
        houseSweep.setScheduledTime(houseInspection.getScheduledTime());
        houseSweep.setSweepState(HouseSweepEnum.SWEEP_STATE_NO.getValue());
        houseSweep.setSweepType(HouseSweepEnum.SWEEP_TYPE_EXCHANGE.getValue());
        houseSweep.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        houseSweep.setOrderId(order.getOrderId());
        houseSweep.setHouseId(house.getHouseId());
        String houseSweepId = "W" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseSweep.setHouseSweepId(houseSweepId);
        houseSweep.setCreateTime(DateUtils.getNowDate());
        houseSweepService.insertHouseSweep(houseSweep);

        List<SweepProcessRecord> sweepProcessRecordList = new ArrayList<>();
        List<InspectionProcessRecord> inspectionProcessRecordList = new ArrayList<>();
        for (CleaningProcess process : cleaningProcessList) {
            InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
            inspectionProcessRecord.setHouseInspectionId(houseInspection.getHouseInspectionId());
            inspectionProcessRecord.setTenantId(houseInspection.getTenantId());
            inspectionProcessRecord.setCleaningProcessId(process.getId());
            inspectionProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
            inspectionProcessRecord.setParentId(process.getParentId());
            inspectionProcessRecord.setSort(process.getSort());
            inspectionProcessRecord.setCreateTime(new Date());
            inspectionProcessRecordList.add(inspectionProcessRecord);

            if (process.getParentId() == null) {
                SweepProcessRecord sweepProcessRecord = new SweepProcessRecord();
                sweepProcessRecord.setHouseSweepId(houseSweep.getHouseSweepId());
                sweepProcessRecord.setTenantId(houseSweep.getTenantId());
                sweepProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
                sweepProcessRecord.setSort(process.getSort());
                sweepProcessRecord.setCreateTime(new Date());
                sweepProcessRecordList.add(sweepProcessRecord);
            }
        }

        iInspectionProcessRecordService.insertInspectionProcessRecordList(inspectionProcessRecordList);
        sweepProcessRecordService.insertSweepProcessRecordList(sweepProcessRecordList);
    }

    private AjaxResult sweepAndInspection(HouseInspection houseInspection, Order order, House house, List<CleaningProcess> cleaningProcessList, Long cleanerId) {
        Cleaner byCleanerId = cleanerService.selectCleanerByCleanerId(cleanerId);
        if (ObjectUtil.isEmpty(byCleanerId)) {
            throw new ServiceException("保洁人员不存在");
        }
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_YES.getValue());
        houseInspection.setInspectionType(HouseInspectionEnum.INSPECTION_TYPE_EXCHANGE.getValue());
        houseInspection.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        houseInspection.setOrderId(order.getOrderId());
        houseInspection.setHouseId(house.getHouseId());
        String houseInspectionId = "I" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseInspection.setHouseInspectionId(houseInspectionId);
        houseInspection.setCreateTime(DateUtils.getNowDate());
        houseInspection.setHomeInspectorName(byCleanerId.getCleanerName());
        houseInspection.setCleanerUserId(byCleanerId.getCleanerUserId());
        houseInspection.setCleanerId(byCleanerId.getCleanerId());
        houseInspection.setUpdateTime(DateUtils.getNowDate());
        houseInspectionMapper.insertHouseInspection(houseInspection);


        HouseSweep houseSweep = new HouseSweep();
        houseSweep.setOperatorId(houseInspection.getOperatorId());
        houseSweep.setTenantId(houseInspection.getTenantId());
        houseSweep.setScheduledTime(houseInspection.getScheduledTime());
        houseSweep.setSweepState(HouseSweepEnum.SWEEP_STATE_YES.getValue());
        houseSweep.setSweepType(HouseSweepEnum.SWEEP_TYPE_EXCHANGE.getValue());
        houseSweep.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        houseSweep.setOrderId(order.getOrderId());
        houseSweep.setHouseId(house.getHouseId());
        String houseSweepId = "W" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseSweep.setHouseSweepId(houseSweepId);
        houseSweep.setCreateTime(DateUtils.getNowDate());
        houseSweep.setHomeSweepName(byCleanerId.getCleanerName());
        houseSweep.setCleanerUserId(byCleanerId.getCleanerUserId());
        houseSweep.setCleanerId(byCleanerId.getCleanerId());
        houseSweepService.insertHouseSweep(houseSweep);


        List<SweepProcessRecord> sweepProcessRecordList = new ArrayList<>();
        List<InspectionProcessRecord> inspectionProcessRecordList = new ArrayList<>();
        for (CleaningProcess process : cleaningProcessList) {
            InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
            inspectionProcessRecord.setHouseInspectionId(houseInspection.getHouseInspectionId());
            inspectionProcessRecord.setTenantId(houseInspection.getTenantId());
            inspectionProcessRecord.setCleaningProcessId(process.getId());
            inspectionProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
            inspectionProcessRecord.setParentId(process.getParentId());
            inspectionProcessRecord.setSort(process.getSort());
            inspectionProcessRecord.setCreateTime(new Date());
            inspectionProcessRecordList.add(inspectionProcessRecord);


            if (process.getParentId() == null) {
                SweepProcessRecord sweepProcessRecord = new SweepProcessRecord();
                sweepProcessRecord.setHouseSweepId(houseSweep.getHouseSweepId());
                sweepProcessRecord.setTenantId(houseSweep.getTenantId());
                sweepProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
                sweepProcessRecord.setSort(process.getSort());
                sweepProcessRecord.setCreateTime(new Date());
                sweepProcessRecordList.add(sweepProcessRecord);
            }
        }
        iInspectionProcessRecordService.insertInspectionProcessRecordList(inspectionProcessRecordList);
        sweepProcessRecordService.insertSweepProcessRecordList(sweepProcessRecordList);


        // 短信通知
        BizUserBusiness userBusiness = bizUserBusinessService.selectBizUserBusinessByUserId(byCleanerId.getCleanerUserId(), TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(userBusiness)) {
            throw new ServiceException("企业用户不存在");
        }
        Boolean smsInspectionData = smsUtils.sendTemplateSmsWithData(userBusiness.getPhonenumber(), smsConfig.getInspectionTemplateCode(), new String[]{DateUtil.formatDateTime(houseInspection.getScheduledTime()), houseInspection.getFullAddress()});
        Boolean smsSweepData = smsUtils.sendTemplateSmsWithData(userBusiness.getPhonenumber(), smsConfig.getSweepTemplateCode(), new String[]{DateUtil.formatDateTime(houseSweep.getScheduledTime()), houseSweep.getFullAddress()});
        if (smsInspectionData && smsSweepData) {
            return AjaxResult.success("派单成功");
        }
        return AjaxResult.error("派单失败");

    }


    private int sendInspection(HouseInspection houseInspection, Order order, House house, List<CleaningProcess> cleaningProcessList, Long cleanerId) {
        Cleaner byCleanerId = cleanerService.selectCleanerByCleanerId(cleanerId);
        if (ObjectUtil.isEmpty(byCleanerId)) {
            throw new ServiceException("保洁人员不存在");
        }
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_YES.getValue());
        houseInspection.setFullAddress(house.getEstateName() + house.getBuildingName() + "栋" + house.getUnitName() + "单元" + house.getRoomNumber());
        if (ObjectUtil.isNotEmpty(order)) {
            houseInspection.setOrderId(order.getOrderId());
        }
        houseInspection.setHouseId(house.getHouseId());
        String houseInspectionId = "I" + System.currentTimeMillis() + RandomUtils.nextInt(10000, 100000);
        houseInspection.setHouseInspectionId(houseInspectionId);
        houseInspection.setCreateTime(DateUtils.getNowDate());
        houseInspection.setHomeInspectorName(byCleanerId.getCleanerName());
        houseInspection.setCleanerUserId(byCleanerId.getCleanerUserId());
        houseInspection.setCleanerId(byCleanerId.getCleanerId());
        houseInspection.setUpdateTime(DateUtils.getNowDate());
        houseInspectionMapper.insertHouseInspection(houseInspection);

        List<InspectionProcessRecord> inspectionProcessRecordList = new ArrayList<>();
        for (CleaningProcess process : cleaningProcessList) {
            InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
            inspectionProcessRecord.setHouseInspectionId(houseInspection.getHouseInspectionId());
            inspectionProcessRecord.setTenantId(houseInspection.getTenantId());
            inspectionProcessRecord.setCleaningProcessId(process.getId());
            inspectionProcessRecord.setCleaningProcessName(process.getCleaningProcessName());
            inspectionProcessRecord.setParentId(process.getParentId());
            inspectionProcessRecord.setSort(process.getSort());
            inspectionProcessRecord.setCreateTime(new Date());
            inspectionProcessRecordList.add(inspectionProcessRecord);
        }
        iInspectionProcessRecordService.insertInspectionProcessRecordList(inspectionProcessRecordList);


        // 短信通知
        BizUserBusiness userBusiness = bizUserBusinessService.selectBizUserBusinessByUserId(byCleanerId.getCleanerUserId(), TenantContext.getTenantId());
        if (ObjectUtil.isEmpty(userBusiness)) {
            throw new ServiceException("企业用户不存在");
        }
        Boolean smsInspectionData = smsUtils.sendTemplateSmsWithData(userBusiness.getPhonenumber(), smsConfig.getInspectionTemplateCode(), new String[]{DateUtil.formatDateTime(houseInspection.getScheduledTime()), houseInspection.getFullAddress()});
        if (smsInspectionData) {
            return 1;
        }
        return 0;

    }

    @Override
    @Transactional
    public int editHouseInspectionList(HouseInspection houseInspection) {
        HouseInspection inspection = houseInspectionMapper.selectHouseInspectionByHouseInspectionId(houseInspection.getHouseInspectionId());
        if (ObjectUtil.isEmpty(inspection)) {
            throw new ServiceException("数据已被删除，请刷新后再试");
        }
        if (inspection.getInspectionState().equals(HouseInspectionEnum.INSPECTION_STATE_NO.getValue())) {
            throw new ServiceException("数据状态异常，请刷新后再试");
        }
        if (!inspection.getCleanerUserId().equals(houseInspection.getCleanerUserId())) {
            throw new ServiceException("验房人数据异常，请刷新后再试");
        }


        List<HousePicture> housePictureList = new ArrayList<>();

        houseInspection.setInspectionResult(HouseInspectionEnum.INSPECTION_RESULT_NORMAL.getValue());
        List<InspectionProcessRecord> inspectionProcessRecordList = houseInspection.getInspectionProcessRecordList();
        if (CollectionUtil.isEmpty(inspectionProcessRecordList)) {
            throw new ServiceException("验房过程不存在");
        }
        Map<Long, String> processMap = inspectionProcessRecordList.stream().filter(x -> x.getParentId() == null).collect(Collectors.toMap(InspectionProcessRecord::getId, InspectionProcessRecord::getCleaningProcessName));
        // 生成分组编号
        String packetIdentification = RandomUtil.randomStringWithoutStr(10, "0123456789");
        for (InspectionProcessRecord inspectionProcessRecord : inspectionProcessRecordList) {
            if (inspectionProcessRecord.getParentId() == null && StrUtil.isEmpty(inspectionProcessRecord.getFacilitiesImg())) {
                throw new ServiceException(inspectionProcessRecord.getCleaningProcessName() + "请拍摄现场图片");
            }
            if (StrUtil.equals(inspectionProcessRecord.getFacilitiesState(), HouseInspectionEnum.INSPECTION_RESULT_DAMAGE.getValue()) && StrUtil.isEmpty(inspectionProcessRecord.getFacilitiesImg())) {
                throw new ServiceException(inspectionProcessRecord.getCleaningProcessName() + "请拍摄损坏图片");
            }
            String facilitiesImg = inspectionProcessRecord.getFacilitiesImg();
            if (StrUtil.isNotEmpty(facilitiesImg)) {
                String[] split = facilitiesImg.split(",");
                if (split.length > 9) {
                    throw new ServiceException("最多上次9张打扫后图片");
                }
            }
            if (StrUtil.equals(inspectionProcessRecord.getFacilitiesState(), HouseInspectionEnum.INSPECTION_RESULT_DAMAGE.getValue())) {
                houseInspection.setInspectionResult(HouseInspectionEnum.INSPECTION_RESULT_DAMAGE.getValue());
            }
            inspectionProcessRecord.setUpdateTime(new Date());


            // 封装房屋相册记录
            // 拼接位置和检查点
            String cleaningProcessName = inspectionProcessRecord.getCleaningProcessName();
            Long parentId = inspectionProcessRecord.getParentId();
            if (parentId != null) {
                String processName = processMap.get(parentId);
                cleaningProcessName = processName + "-" + cleaningProcessName;
            }
            HousePicture housePicture = new HousePicture(inspection.getHouseId(), inspection.getFullAddress(), HouseConstants.HOUSE_PICTURE_INSPECTION, houseInspection.getUpdateBy(),
                    houseInspection.getOperatorId(), facilitiesImg.split(",").length, facilitiesImg, inspection.getTenantId(),
                    cleaningProcessName, inspectionProcessRecord.getFacilitiesState(), inspection.getHouseInspectionId(), packetIdentification);
            housePicture.setCreateTime(new Date());
            housePictureList.add(housePicture);

        }
        houseInspection.setInspectionState(HouseInspectionEnum.INSPECTION_STATE_FULFILL.getValue());
        houseInspection.setFinishTime(new Date());
        houseInspection.setVersion(inspection.getVersion());
        int i = houseInspectionMapper.updateHouseInspection(houseInspection);
        if (i == 0) {
            return 0;
        }

        // 新增房屋相册信息
        int j = housePictureService.insertBatchHousePicture(housePictureList);
        if (j == 0) {
            return 0;
        }

        iInspectionProcessRecordService.updateInspectionProcessRecordList(inspectionProcessRecordList);
        return 1;
    }

    @Override
    public List<HouseInspection> selectHouseInspectionByOrderId(HouseInspection houseInspection) {
        return houseInspectionMapper.selectHouseInspectionByOrderId(houseInspection);
    }


    /**
     * 获取验房记录设备损坏信息
     */
    @Override
    public HouseInspection getProcessInfo(HouseInspection houseInspection) {
        if (houseInspection.getHouseInspectionIds() == null || houseInspection.getHouseInspectionIds().length == 0) {
            throw new ServiceException("验房记录不存在");
        }
        List<HouseInspection> houseInspectionList = houseInspectionMapper.selectHouseInspectionByHouseInspectionIds(houseInspection);
        if (CollectionUtil.isEmpty(houseInspectionList)) {
            throw new ServiceException("验房记录不存在");
        }
        if (houseInspectionList.size() != houseInspection.getHouseInspectionIds().length) {
            throw new ServiceException("数据异常，请刷新后再试");
        }
        House house = houseService.selectHouseById(houseInspectionList.get(0).getHouseId());
        if (ObjectUtil.isEmpty(house)) {
            throw new ServiceException("房源不存在");
        }
        InspectionProcessRecord inspectionProcessRecord = new InspectionProcessRecord();
        inspectionProcessRecord.setHouseInspectionIds(houseInspection.getHouseInspectionIds());
        inspectionProcessRecord.setTenantId(TenantContext.getTenantId());
        List<InspectionProcessRecord> inspectionProcessRecordList = iInspectionProcessRecordService.selectInspectionProcessRecordByHouseInspectionIds(inspectionProcessRecord);

        List<InspectionProcessRecord> inspectionProcessRecords = iInspectionProcessRecordService.selectInspectionProcessRecordByHouseInspectionIdsAndParentId(inspectionProcessRecord);
        Map<Long, String> processMap = inspectionProcessRecords.stream().filter(x -> x.getParentId() == null).collect(Collectors.toMap(InspectionProcessRecord::getCleaningProcessId, InspectionProcessRecord::getCleaningProcessName));

        List<InspectionProcessRecord> processRecordList = new ArrayList();
        if (CollectionUtil.isNotEmpty(inspectionProcessRecordList)) {
            for (InspectionProcessRecord processRecord : inspectionProcessRecordList) {
                if (StrUtil.equals(processRecord.getFacilitiesState(), HouseInspectionEnum.INSPECTION_RESULT_DAMAGE.getValue())) {
                    InspectionProcessRecord newProcessRecord = new InspectionProcessRecord();
                    Long parentId = processRecord.getParentId();
                    if (parentId != null) {
                        String processName = processMap.get(parentId);
                        newProcessRecord.setCleaningProcessName(house.getRoomNumber() + processName + processRecord.getCleaningProcessName());
                        processRecordList.add(newProcessRecord);
                    }


                }
            }
        }
        houseInspection.setInspectionProcessRecordList(processRecordList);
        return houseInspection;
    }

    @Override
    public List<HouseInspection> selectHouseInspectionByCleanerIds(Long[] cleanerIds) {
        return houseInspectionMapper.selectHouseInspectionByCleanerIds(cleanerIds);
    }

    @Override
    public Map<String, Integer> statistics(Long userId) {
        Map<String, Integer> map = new HashMap<>();
        Integer inspectionNumber = houseInspectionMapper.selectHouseInspectionNumber(TenantContext.getTenantId(), userId);
        Integer sweepNumber = houseSweepService.selectHouseSweepNumber(TenantContext.getTenantId(), userId);
        map.put("inspectionNumber", inspectionNumber);
        map.put("sweepNumber", sweepNumber);
        return map;
    }

}
